﻿using MySSO.Core;
using MySSO.Core.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MySSOMVC.Controllers
{
    public class HomeController : Controller
    {
        private readonly MemoryCacheManager memoryCacheManager;
        private readonly AdminUserService _adminUserService;
        private readonly WebHelper _webHelper;
        private readonly string tokensecret = System.Configuration.ConfigurationManager.AppSettings["tokensecret"];
        public HomeController()
        {
            memoryCacheManager = new MemoryCacheManager();
            _adminUserService = new AdminUserService();
            _webHelper = new WebHelper();
            _adminUserService = new AdminUserService();
        }
        public ActionResult Index()
        {
            HttpCookie AuthCookie = Request.Cookies[AppConstants.Cookie.AUTH_COOKIE];
            string uid="0";
            if (AuthCookie != null && CheckCookie(AuthCookie,ref uid))
            {
                var user = _adminUserService.GetAdminUserEntityById(long.Parse(uid));
                if (user != null && !user.Disable)
                {
                    return View();
                }
                else
                {
                    return RedirectToAction("Login", "Authorize");
                }
                   
            }
            else
            {
                return RedirectToAction("Login", "Authorize");
            }
           
        }

     

        /// <summary>
        /// If the Cookie is available, check the expiry of the authentication Cookie.
        /// Also, add Token and redirect
        /// </summary>
        /// <param name="AuthCookie"></param>
        /// <param name="ReturnUrl"></param>
        private bool CheckCookie(HttpCookie AuthCookie,ref string useid)
        {
            bool result = false;
            string Token = Utility.GetCookieValue(AuthCookie);
            string idtoken = memoryCacheManager.Get<string>(Token);

            DateTime expirytime = Utility.GetExpirationDate(AuthCookie);
            //Check if the Cookie is expired and Token is available
            try
            {
                IDictionary<string, object> payload = JWTHelper.Decode(idtoken, tokensecret);
                UserSSoModel userSSoModel = new UserSSoModel();
                userSSoModel.token = payload["token"].ToString();
                userSSoModel.uid = payload["uid"].ToString();
                userSSoModel.username = payload["name"].ToString();

                //刷新token,token过期时间为5分钟
                idtoken = IdtokenHelper.RefreshIdtoken(payload, AppConstants.TokenExpireTime, tokensecret);
                memoryCacheManager.Set(Token, idtoken, 30);
                useid = userSSoModel.uid;
                result = true;
            }
            catch
            {
                //Cookie is expired. So, remove the Cookie from the Response
                RemoveCookie(AuthCookie);
                //Mark the user's presence as Null in the application scope
                memoryCacheManager.Remove(Token);
                //Redirect to the site URL
                //return RedirectToAction("Login", "Authorize", new { ReturnUrl = ReturnUrl, State = State });
                //return RedirectAction(ReturnUrl);
                result = false;
            }
            if (CookieExpired(expirytime))
            {
                //Cookie is expired. So, remove the Cookie from the Response
                RemoveCookie(AuthCookie);
                //Mark the user's presence as Null in the application scope
                memoryCacheManager.Remove(Token);
                //Redirect to the site URL
                //return RedirectToAction("Login", "Authorize", new { ReturnUrl = ReturnUrl, State = State });
                //return RedirectAction(ReturnUrl);
                result = false;

            }
            else
            {
                //Check if Sliding expiration is set to true in web.config
                if (Config.SLIDING_EXPIRATION)
                {
                    //Sliding expiration is set to true. So, increase the expiry time for the Cookie

                    AuthCookie = IncreaseCookieExpiryTime(AuthCookie);
                }
            }

            return result;
           
        }

        /// <summary>
        /// Removes Cookie from the response
        /// </summary>
        /// <param name="Cookie"></param>
        private void RemoveCookie(HttpCookie Cookie)
        {
            Response.Cookies.Remove(Cookie.Name);

            HttpCookie myCookie = new HttpCookie(Cookie.Name);
            myCookie.Expires = DateTime.Now.AddDays(-1d);
            Response.Cookies.Add(myCookie);
        }

        /// <summary>
        /// Determines whether the Cookie is expired or not
        /// </summary>
        /// <param name="expirytime"></param>
        /// <returns></returns>
        private bool CookieExpired(DateTime expirytime)
        {
            return expirytime.CompareTo(DateTime.Now) < 0;
        }

        /// <summary>
        /// Increases Cookie expiry time
        /// </summary>
        /// <param name="AuthCookie"></param>
        /// <returns></returns>
        private HttpCookie IncreaseCookieExpiryTime(HttpCookie AuthCookie)
        {
            string Token = Utility.GetCookieValue(AuthCookie);
            DateTime Expirytime = Utility.GetExpirationDate(AuthCookie);
            DateTime IncreasedExpirytime = Expirytime.AddMinutes(Config.AUTH_COOKIE_TIMEOUT_IN_MINUTES);

            Response.Cookies.Remove(AuthCookie.Name);

            HttpCookie NewCookie = new HttpCookie(AuthCookie.Name);
            NewCookie.Value = Utility.BuildCookueValue(Token, Config.AUTH_COOKIE_TIMEOUT_IN_MINUTES);

            Response.Cookies.Add(NewCookie);

            return NewCookie;
        }
    }
}